prevent assertion failures in nmea reader (#1332)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Fri, 30 Aug 2024 22:31:11 +0000 (16:31 -0600)
committerGitHub <noreply@github.com>
Fri, 30 Aug 2024 22:31:11 +0000 (16:31 -0600)
* replace all empty nmea fields with 0.

including adjacent empty fileds, i.e. ",,," -> ",0,0,".

* defend against indexing past end of arrays.

prevents assertion failures in qstring.h operator[].

also consistently default longitude direction.

nmea.cc

diff --git a/nmea.cc b/nmea.cc
index 2a2c90d0db0a35c134bf1db7acfd82183d72bdba..0e1f3521329510b23bed977277f766873a2246db 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -386,11 +386,11 @@ NmeaFormat::gpgll_parse(const QString& ibuf)
   double latdeg = 0;
   if (fields.size() > 1) latdeg = fields[1].toDouble();
   QChar latdir = 'N';
-  if (fields.size() > 2) latdir = fields[2][0];
+  if ((fields.size() > 2) && (fields[2].size() > 0)) latdir = fields[2][0];
   double lngdeg = 0;
   if (fields.size() > 3) lngdeg = fields[3].toDouble();
   QChar lngdir = 'E';
-  if (fields.size() > 4) lngdir = fields[4][0];
+  if ((fields.size() > 4) && (fields[4].size() > 0)) lngdir = fields[4][0];
   QTime hms;
   if (fields.size() > 5) hms = nmea_parse_hms(fields[5]);
   bool valid = false;
@@ -434,11 +434,11 @@ NmeaFormat::gpgga_parse(const QString& ibuf)
   double latdeg = 0;
   if (fields.size() > 2) latdeg = fields[2].toDouble();
   QChar latdir = 'N';
-  if (fields.size() > 3) latdir = fields[3][0];
+  if ((fields.size() > 3) && (fields[3].size() > 0)) latdir = fields[3][0];
   double lngdeg = 0;
   if (fields.size() > 4) lngdeg = fields[4].toDouble();
-  QChar lngdir = 'W';
-  if (fields.size() > 5) lngdir = fields[5][0];
+  QChar lngdir = 'E';
+  if ((fields.size() > 5) && (fields[5].size() > 0)) lngdir = fields[5][0];
   int fix = fix_unknown;
   if (fields.size() > 6) fix = fields[6].toInt();
   int nsats = 0;
@@ -448,11 +448,11 @@ NmeaFormat::gpgga_parse(const QString& ibuf)
   double alt = unknown_alt;
   if (fields.size() > 9) alt = fields[9].toDouble();
   QChar altunits ='M';
-  if (fields.size() > 10) altunits = fields[10][0];
+  if ((fields.size() > 10) && (fields[10].size() > 0)) altunits = fields[10][0];
   double geoidheight = unknown_alt;
   if (fields.size() > 11) geoidheight = fields[11].toDouble();
   QChar geoidheightunits = 'M';
-  if (fields.size() > 12) geoidheightunits = fields[12][0];
+  if ((fields.size() > 12) && (fields[12].size() > 0)) geoidheightunits = fields[12][0];
 
   /*
    * In serial mode, allow the fix with an invalid position through
@@ -522,15 +522,15 @@ NmeaFormat::gprmc_parse(const QString& ibuf)
   QTime hms;
   if (fields.size() > 1) hms = nmea_parse_hms(fields[1]);
   QChar fix = 'V'; // V == "Invalid"
-  if (fields.size() > 2) fix = fields[2][0];
+  if ((fields.size() > 2) && (fields[2].size() > 0)) fix = fields[2][0];
   double latdeg = 0;
   if (fields.size() > 3) latdeg = fields[3].toDouble();
   QChar latdir = 'N';
-  if (fields.size() > 4) latdir = fields[4][0];
+  if ((fields.size() > 4) && (fields[4].size() > 0)) latdir = fields[4][0];
   double lngdeg = 0;
   if (fields.size() > 5) lngdeg = fields[5].toDouble();
-  QChar lngdir = 'W';
-  if (fields.size() > 6) lngdir = fields[6][0];
+  QChar lngdir = 'E';
+  if ((fields.size() > 6) && (fields[6].size() > 0)) lngdir = fields[6][0];
   double speed = 0;
   if (fields.size() > 7) speed = fields[7].toDouble();
   double course = 0;
@@ -604,11 +604,11 @@ NmeaFormat::gpwpl_parse(const QString& ibuf)
   double latdeg = 0;
   if (fields.size() > 1) latdeg = fields[1].toDouble();
   QChar latdir = 'N';
-  if (fields.size() > 2) latdir = fields[2][0];
+  if ((fields.size() > 2) && (fields[2].size() > 0)) latdir = fields[2][0];
   double lngdeg = 0;
   if (fields.size() > 3) lngdeg = fields[3].toDouble();
   QChar lngdir = 'E';
-  if (fields.size() > 4) lngdir = fields[4][0];
+  if ((fields.size() > 4) && (fields[4].size() > 0)) lngdir = fields[4][0];
   QString sname;
   if (fields.size() > 5) sname = fields[5];
 
@@ -662,7 +662,7 @@ NmeaFormat::gpgsa_parse(const QString& ibuf) const
   // 0 = "GPGSA"
   // 1 = Mode. Ignored
   QChar fix;
-  if (nfields > 2) {
+  if ((nfields > 2) && (fields[2].size() > 0)) {
     fix = fields[2][0];
   }
 
@@ -943,7 +943,9 @@ NmeaFormat::nmea_parse_one_line(const QByteArray& ibuf)
      for that field.  Rather than change all the parse routines, we first
      substitute a default value of zero for any missing field.
   */
-  tbuf.replace(",,", ",0,");
+  while (tbuf.contains(",,")) {
+    tbuf.replace(",,", ",0,");
+  }
 
   if (notalkerid_strmatch(tbuf, "WPL")) {
     gpwpl_parse(tbuf);